This lecture will consist of explaining what a function is in R and how to create one. Functions will be one of our main building blocks when we construct larger and larger amounts of code to solve problems.
So what is a function?
Formally, a function is a useful device that groups together a set of statements so they can be run more than once. They can also let us specify parameters that can serve as inputs to the functions.
On a more fundamental level, functions allow us to not have to repeatedly write the same code again and again. If you remember back to the lessons on strings and lists, remember that we used a function length() to get the length of a string. Since checking the length of a sequence is a common task you would want to write a function that can do this repeatedly at command. Functions will be one of most basic levels of reusing code in R, and it will also allow us to start thinking about program design.
We already have seen built-in functions and we can use the help function to discover the arguments that the functions take in.
help(sum)
Notice how the format is:
name_of_function(input1,input2,....)
So how do we create this ourselves? Here is the syntax for writing your own function:
name_of_function <- function(arg1,arg2,...){
# Code that gets executed when function is called
}
Let's see some examples.
# Simple function, no inputs!
hello <- function(){
print('hello!')
}
hello()
helloyou <- function(name){
print(paste('hello ',name))
}
helloyou('Sammy')
add_num <- function(num1,num2){
print(num1+num2)
}
add_num(5,10)
Notice that so far we've had to define every single argument in the function when using it, but we can also have default values by using an equals sign, for example:
hello_someone <- function(name='Frankie'){
print(paste('Hello ',name))
}
# uses default
hello_someone()
# overwrite default
hello_someone('Sammy')
You'll see lots of built-in functions use default values for a variety of tasks, where the users will usually need a particular value.
So far we've only been printing out results, but what if we wanted to return the results so that we could assign them to a variable, we can use the return keyword for this task in the following manner:
formal <- function(name='Sam',title='Sir'){
return(paste(title,' ',name))
}
formal()
formal('Issac Newton')
Notice how we aren't printing, we are returning, meaning we can assign this to a variable:
var <- formal('Marie Curie','Ms.')
var
This is the sort of syntax you want to use for your functions when you want to pass arguments to them, and then get some sort of result in return.
Scope is the term we use to describe how objects and variable get defined within R. When discussing scope with functions, as a general rule we can say that if a variable is defined only inside a function than its scope is limited to that function. For example, consider the following function:
# Multiplies input by 5
times5 <- function(input) {
result <- input ^ 2
return(result)
}
pow_two(4)
result # Not defined outside the scope of the function
input # Not defined outside the scope of the function
These error indicate that these variables are only defined inside the scope of the function. So variables defined inside of a function are only defined (or redefined) inside of that function. However, variables assigned outside of the function are global variables, and the function will have access to them due to their scope. For example:
v <- "I'm global v"
stuff <- "I'm global stuff"
fun <- function(stuff){
print(v)
stuff <- 'Reassign stuff inside func'
print(stuff)
}
print(v) #print v
print(stuff) #print stuff
fun(stuff) # pass stuff to function
# reassignment only happens in scope of function
print(stuff)
So what is happening above? The following happens
print(v) will check for the global variable v, the outer scope
print(stuff) will also check for the global variable stuff
fun(stuff) will accept an argument stuff, print out v, and then reassign stuff (in the scope of the function) and print out stuff. Notice two things:
Check out the function below and make sure you understand it:
double <- function(a) {
a <- 2*a
a
}
var <- 5
double(var)
var
Great we've learned a lot! Now its time to put your understanding to the test with some questions!